import network
import asyncio
import ujson as json
import os
import gc
import time

ssid = '关注B站：ideaswork'
password = '感谢支持~！'

station = network.WLAN(network.STA_IF)
station.active(True)
time.sleep(0.5)
station.connect(ssid, password)

while not station.isconnected():
    pass

print('Connection successful')
print(station.ifconfig())

# 打印当前可用内存
print("Available memory:", gc.mem_free(), "bytes")

db = []

def load_db(filename="db.jsonl"):
    global db
    if filename in os.listdir():
        with open(filename, "r") as file:
            for line in file:
                record = json.loads(line)
                db.append(record)
        
    else:
        print(f"Initialized new database structure as {filename} was not found")

# 保存数据库到文件
def save_db(filename="db.jsonl"):
    global db
    with open(filename, "w") as file:
        for part in db:
            file.write(json.dumps(part) + "\n")

def init_db():
    if "db.jsonl" not in os.listdir():
        save_db()  # Save the newly created database to file

init_db()


# 添加元件
def add_part(part):
    global db
    gc.collect()  # 在复杂操作前垃圾回收
    part['id'] = max([p['id'] for p in db] + [0]) + 1  # Ensure unique ID
    db.append(part)
    save_db()

# 批量添加元件
def add_parts(parts):
    global db
    gc.collect()  # 在复杂操作前垃圾回收
    for part in parts:
        part['id'] = max([p['id'] for p in db] + [0]) + 1  # Ensure unique ID
        db.append(part)
    save_db()

# 删除元件
def del_part(part_id):
    print(f"Received part_id to delete: {part_id}")
    global db
    gc.collect()  # 在复杂操作前垃圾回收
    db = [part for part in db if part.get("id") != part_id]
    save_db()

# 更新元件
def update_part(part_id, updated_part):
    global db
    gc.collect()  # 在复杂操作前垃圾回收
    for part in db:
        if part["id"] == part_id:
            part.update(updated_part)
            break
    save_db()

# 获取元件信息
def get_part(part_id):
    global db
    gc.collect()  # 在复杂操作前垃圾回收
    for part in db:
        if part["id"] == part_id:
            return part
    return None

from microdot import Microdot, Response

app = Microdot()
Response.default_content_type = 'application/json'

@app.route('/inventory', methods=['GET'])
async def get_inventory(request):
    print(" memory:", gc.mem_free(), "bytes")
    gc.collect()
    print(" memory:", gc.mem_free(), "bytes")
    global db

    def generate():
        try:
            for part in db:
                yield json.dumps(part) + "\n"
        except Exception as e:
            yield f"Error generating inventory data: {e}"

    return Response(generate(), headers={'Content-Type': 'application/json'})

@app.route('/inventory/<int:part_id>', methods=['GET'])
async def get_inventory_part(request, part_id):
    gc.collect()  # 在复杂操作前垃圾回收
    part = get_part(part_id)
    if part:
        return part
    else:
        return {'error': 'Part not found'}, 404

@app.route('/inventory', methods=['POST'])
async def add_inventory_part(request):
    gc.collect()  # 在复杂操作前垃圾回收
    part = request.json
    if part:
        try:
            add_part(part)
            return part
        except Exception as e:
            print(f"Error adding part: {e}")
            return {'error': 'Failed to add part, please try again'}, 500
    else:
        return {'error': 'Invalid data'}, 400

@app.route('/inventory/batch', methods=['POST'])
async def add_inventory_parts(request):
    gc.collect()  # 在复杂操作前垃圾回收
    try:
        parts = request.json
        if parts and isinstance(parts, list):
            try:
                add_parts(parts)
                return {'message': 'Parts added successfully'}
            except Exception as e:
                print(f"Error adding parts: {e}")
                return {'error': 'Failed to add parts, please try again'}, 500
        else:
            return {'error': 'Invalid data'}, 400
    except Exception as e:
        return {'error': 'An error occurred while processing the request'}, 500

@app.route('/inventory/<int:part_id>', methods=['PUT'])
async def update_inventory_part(request, part_id):
    gc.collect()  # 在复杂操作前垃圾回收
    updated_part = request.json
    if updated_part:
        try:
            update_part(part_id, updated_part)
            return updated_part
        except Exception as e:
            print(f"Error updating part: {e}")
            return {'error': 'Failed to update part, please try again'}, 500
    else:
        return {'error': 'Invalid data'}, 400

@app.route('/inventory/<int:part_id>', methods=['DELETE'])
async def delete_inventory_part(request, part_id):
    gc.collect()  # 在复杂操作前垃圾回收
    try:
        del_part(part_id)
        return {'message': 'Part deleted successfully'}
    except Exception as e:
        print(f"Error deleting part: {e}")
        return {'error': 'Failed to delete part, please try again'}, 500

@app.route('/')
async def index(request):
    def generate():
        try:
            with open('index.html', 'r') as file:
                # 增大读取块的大小以减少I/O操作次数
                while True:
                    chunk = file.read(200)  # 增加到1024字节
                    if not chunk:
                        break
                    yield chunk
        except Exception as e:
            yield f"Error loading index.html: {e}"
        finally:
            # 确保文件被正确关闭
            file.close()
    print("Available memory:", gc.mem_free(), "bytes")
    return Response(generate(), headers={'Content-Type': 'text/html'})

async def main():
    try:
        load_db()
        print("Available memory:", gc.mem_free(), "bytes")
        server = asyncio.create_task(app.start_server(port=80))
        print("Available memory:", gc.mem_free(), "bytes")
        await server
    except Exception as e:
        pass

asyncio.run(main())
